﻿using Cinch;
using FR.SAFTAnalyser.Model;
using FR.SAFTAnalyser.Services;
using FR.SAFTAnalyser.ViewModels;
using MEFedMVVM.Common;
using MEFedMVVM.ViewModelLocator;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Windows.Data;

namespace FR.SAFTAnalyser
{
    [ExportViewModel("MainWindowViewModel")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class MainWindowViewModel : ViewModelBase
    {
        [ImportingConstructor]
        public MainWindowViewModel(IOpenFileService ofs, IMessageBoxService mbs)
        {
            if (!Designer.IsInDesignMode)
            {
                this.openFileService = ofs;
                this.messageBoxService = mbs;
                Mediator.Instance.Register(this);
                //Commands
                SettingsCommand = new SimpleCommand<Object, Object>(Settings);
                AboutCommand = new SimpleCommand<Object, Object>(About);
                UpdateVersionCommand = new SimpleCommand<object, object>(CanUpdateVersion, UpdateVersion);

                //FindUpdates();
                MensagemStatus = UpdateStatusMessage();
            }
        }

        IOpenFileService openFileService;
        IMessageBoxService messageBoxService;
        ObservableCollection<WorkspaceViewModel> _workspaces;

        #region Commands
        public SimpleCommand<object, object> SettingsCommand { get; private set; }

        public void Settings(Object args)
        {
            //para alterar, usar o serviço injectado
            FR.SAFTAnalyser.Views.SettingsView sv = new Views.SettingsView();
            sv.ShowDialog();
        }

        public SimpleCommand<object, object> AboutCommand { get; private set; }

        public void About(Object args)
        {
            FR.SAFTAnalyser.Views.AboutView av = new Views.AboutView();
            av.ShowDialog();
        }

        public SimpleCommand<object, object> UpdateVersionCommand { get; private set; }

        public void UpdateVersion(Object args)
        {
            SoftwareUpdate su = new SoftwareUpdate();
            su.BeginUpdate();
        }

        public bool CanUpdateVersion(Object args)
        {
            return IsUpdateAvailable;
        }

        #endregion Commands

        #region Binding properties
        string mensagemStatus;
        public string MensagemStatus
        {
            get { return mensagemStatus; }
            set
            {
                mensagemStatus = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.MensagemStatus));
            }
        }

        string mensagemUpdate;
        public string MensagemUpdate
        {
            get { return mensagemUpdate; }
            set
            {
                mensagemUpdate = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.MensagemUpdate));
            }
        }

        /// <summary>
        /// Returns the collection of available workspaces to display.
        /// A 'workspace' is a ViewModel that can request to be closed.
        /// </summary>
        public ObservableCollection<WorkspaceViewModel> Workspaces
        {
            get
            {
                if (_workspaces == null)
                {
                    _workspaces = new ObservableCollection<WorkspaceViewModel>();

                    _workspaces.Add(new SaftViewModel(openFileService));
                    _workspaces.Add(new HeaderViewModel());
                    _workspaces.Add(new InvoicesViewModel());
                    _workspaces.Add(new InvoicesSummaryViewModel());
                    _workspaces.Add(new GeneralLedgerEntriesViewModel());
                    _workspaces.Add(new GeneralLedgerViewModel());
                    _workspaces.Add(new CustomersViewModel());
                    _workspaces.Add(new SupplierViewModel());
                    _workspaces.Add(new ProdutsViewModel());
                    _workspaces.Add(new TaxViewModel());
                    _workspaces.Add(new ErrorMessagesViewModel());
                    _workspaces.Add(new ConvertPemKeyViewModel(openFileService));
                }

                return _workspaces;
            }
            set
            {
                _workspaces = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.Workspaces));
            }
        }

        int selectedIndex;
        public int SelectedIndex
        {
            get { return selectedIndex; }
            set
            {
                selectedIndex = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.SelectedIndex));
            }
        }

        bool isUpdateAvailable;
        public bool IsUpdateAvailable
        {
            get { return isUpdateAvailable; }
            set
            {
                isUpdateAvailable = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.IsUpdateAvailable));
            }
        }

        string userUpdateAction;
        public string UserUpdateAction
        {
            get
            {
                if (string.IsNullOrEmpty(userUpdateAction))
                    userUpdateAction = UpdateAction.UPDATE_AVAILABLE;
                return userUpdateAction;
            }
            set
            {
                userUpdateAction = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.UserUpdateAction));
            }
        }
        #endregion Binding properties

        #region Message mediator
        [MediatorMessageSink(MessageType.SAFT_HASH_RESULTS)]
        private void LoadHashValidationResults(Error[] error)
        {
            this.MensagemStatus = UpdateStatusMessage();
        }
        [MediatorMessageSink(MessageType.SAFT_SCHEMA_RESULTS)]
        private void LoadSchemaValidationResults(Error[] error)
        {
            this.MensagemStatus = UpdateStatusMessage();
        }
        [MediatorMessageSink(MessageType.ERROR_FOUND)]
        private void LoadError(Error[] error)
        {
            this.MensagemStatus = UpdateStatusMessage();
        }
        [MediatorMessageSink(MessageType.EXCEPTION_FOUND)]
        private void LoadException(string exception)
        {
            this.MensagemStatus = exception;
        }

        [MediatorMessageSink(MessageType.UPDATE_AVAILABLE)]
        private void UpdateAvailable(bool updateAvailable)
        {
            IsUpdateAvailable = updateAvailable;
        }
        [MediatorMessageSink(MessageType.UPDATE_STATUS)]
        private void UpdateStatusMessage(string message)
        {
            if (IsUpdateAvailable)
                this.MensagemUpdate = message;
        }
        [MediatorMessageSink(MessageType.UPDATE_READY)]
        private void UpdateReady(bool updateReady)
        {
            if (updateReady)
            {
                CustomDialogResults dr = this.messageBoxService.ShowYesNo(this.MensagemUpdate, "Update", CustomDialogIcons.Question);

                if (dr == CustomDialogResults.Yes)
                    new SoftwareUpdate().RestartApp();
            }
        }

        [MediatorMessageSink(MessageType.FOCUS_INVOICES)]
        private void FocusInvoice(string s)
        {
            InvoicesViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is InvoicesViewModel) as InvoicesViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_INVOICE, s);
        }
        [MediatorMessageSink(MessageType.FOCUS_INVOICES_LINE)]
        private void FocusInvoiceLine(string s)
        {
            InvoicesViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is InvoicesViewModel) as InvoicesViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_INVOICE_LINE, s);
        }
        [MediatorMessageSink(MessageType.FOCUS_HEADER)]
        private void FocusHeader(string s)
        {
            HeaderViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is HeaderViewModel) as HeaderViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);
        }
        [MediatorMessageSink(MessageType.FOCUS_CUSTOMERS)]
        private void FocusCustomer(string s)
        {
            CustomersViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is CustomersViewModel) as CustomersViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_CUSTOMER, s);
        }
        [MediatorMessageSink(MessageType.FOCUS_PRODUCTS)]
        private void FocusProduct(string s)
        {
            ProdutsViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is ProdutsViewModel) as ProdutsViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_PRODUCT, s);
        }
        [MediatorMessageSink(MessageType.FOCUS_SUPPLIERS)]
        private void FocusSupplier(string s)
        {
            SupplierViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is SupplierViewModel) as SupplierViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_SUPPLIER, s);
        }
        [MediatorMessageSink(MessageType.FOCUS_TAXS)]
        private void FocusTax(string s)
        {
            TaxViewModel workspace = this.Workspaces.FirstOrDefault(vm => vm is TaxViewModel) as TaxViewModel;

            if (workspace != null)
                this.SetActiveWorkspace(workspace);

            Mediator.Instance.NotifyColleaguesAsync<string>(MessageType.FOCUS_TAX, s);
        }
        #endregion Message mediator

        #region private methods
        string UpdateStatusMessage()
        {
            string mensagem = "Sem erros";

            if (SAFT.SaftAnalyser.Instance.MensagensErro.Count == 1)
                mensagem = "1 erro";
            else if (SAFT.SaftAnalyser.Instance.MensagensErro.Count > 1)
                mensagem = string.Format("{0} erros.", SAFT.SaftAnalyser.Instance.MensagensErro.Count);

            return mensagem;
        }

        void SetActiveWorkspace(WorkspaceViewModel workspace)
        {
            ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.Workspaces);
            if (collectionView != null)
            {
                collectionView.MoveCurrentTo(workspace);
                this.SelectedIndex = collectionView.CurrentPosition;
            }
        }

        void FindUpdates()
        {
            CheckForUpdates();

            System.Timers.Timer timer = new System.Timers.Timer(3600 * 1000);
            timer.Start();
            timer.Elapsed += timer_Elapsed;

        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            CheckForUpdates();
        }

        void CheckForUpdates()
        {
            SoftwareUpdate su = new SoftwareUpdate();
            su.FindUpdates();
        }
        #endregion private methods
    }
}
